using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

namespace Framework {
    public static class FrameworkEntry
    {
        private static readonly Dictionary<Type, List<Type>> s_Attr2TypeList = new Dictionary<Type, List<Type>>();
        private static readonly ArrayList s_UpdateModules = new ArrayList();
        private static readonly Dictionary<Type, FrameworkModule> s_FrameworkModules = new Dictionary<Type, FrameworkModule>();

        public static void Update(float elapseSeconds, float realElapseSeconds)
        {
            foreach (FrameworkModule module in s_UpdateModules)
            {
                module.Update(elapseSeconds, realElapseSeconds);
            }
        }

        public static void ShutDown()
        {

        }

        public static T GetModule<T>() where T : FrameworkModule
        {
            Type moduleType = typeof(T);
            if (s_FrameworkModules.ContainsKey(moduleType))
            {
                return s_FrameworkModules[moduleType] as T;
            }
            T module = Activator.CreateInstance<T>();
            if(module.NeedUpdate)
            {
                s_UpdateModules.Add(module);
            }
            s_FrameworkModules[moduleType] = module;
            return module;
        }

        public static void InitAssembly()
        {
            Assembly asse = typeof(FrameworkEntry).Assembly;
            foreach (Type type in asse.GetTypes())
            {
                object[] objects = type.GetCustomAttributes(typeof(BaseAttribute), false);
                if (objects.Length == 0)
                {
                    continue;
                }
                BaseAttribute baseAttribute = (BaseAttribute)objects[0];
                List<Type> typeList;
                if (!s_Attr2TypeList.TryGetValue(baseAttribute.AttibuteType, out typeList))
                {
                    typeList = new List<Type>();
                    s_Attr2TypeList[baseAttribute.AttibuteType] = typeList;
                }
                typeList.Add(type);
            }
        }

        public static List<Type> GetTypes(Type attributeType)
        {
            if (!s_Attr2TypeList.ContainsKey(attributeType))
            {
                return new List<Type>();
            }
            return s_Attr2TypeList[attributeType];
        }
    }
}